#ifndef _ML_INTERSTREAM_ANALYSIS_H_
#define _ML_INTERSTREAM_ANALYSIS_H_

#include "MLInterStream.h"
#include "MLRegress_Linear.h"
#include "MLDataPoint.h"
#include "MLDataSet.h"
#include <vector>
#include <map>

using namespace mylablib;


class CMLInterStreamAnalysis
{
public:
	// Constructor and Destructor
	CMLInterStreamAnalysis(CMLInterStream* pStream, std::wofstream* pOutputFile);
	~CMLInterStreamAnalysis(void);

public:
	//

private:
	// Cluster Information
	struct ClusterState_
	{
		ClusterState_()
		{
			time = 0;
		}
		inline double affect()
		{
			return affect(af);
		}

		inline static double affect(const CMLDataPoint& af)
		{
			double sum = 0.0;
			for (int i=0; i<af.size()-1; i++)
			{
				sum += af[i]*af[i];
			}
			sum *= af[af.size()-1]*af[af.size()-1];
			return sum;
		}

		CMLDataPoint center;
		double radius;
		int count;
		int time;
		CMLDataPoint cf;
		CMLDataPoint af;
	};

public:
	// Methods
	int Insert(const CMLDataPoint& p, int nTime);
	int InterventionAnalyze(void);
	int AutoRegress(void);
	int SaveClusterRecords(const std::wstring& wstrFilename);

public:
	// Properites
	inline void SetDimension(int d) { m_nDimension = d; };
	inline void SetRegressParemters(int p1, int p2) { m_nRegressP1 = p1; m_nRegressP2 = p2; };
	inline void SetCoeThreshold(const CMLDataPoint threshold) { m_CoeThreshold = threshold; };
	inline void SetTimeUnit(int u) { m_nTimeUnit = u; };
	inline void SetIntervetionPeriod(int start,int end, int I)
	{
		m_nPeriodStart = start;
		m_nPeriodEnd = end;
		m_nI = I;
	}
	

private:
	// Implementations
	int RecordClusterStates(int nTime);
	int RecordCentroid(void);

private:
	// Fields
	CMLInterStream* m_pStream;
	std::wofstream* m_pOutputFile;
	std::map<int, std::vector<ClusterState_>> m_ClusterSamples;
	int m_nRegressP1; // for preintervention autoregression
	int m_nRegressP2; // for postintervention autoregression
	int m_nDimension;
	int m_nTimeUnit;
	int m_nStartTime;
	int m_nPeriodStart;
	int m_nPeriodEnd;
	int m_nI;
	CMLDataPoint m_Centroid;
	CMLDataPoint m_CoeThreshold;
};


#endif
